package com.coocaa.x.framework.utils;

/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2014年7月18日         Root.Lu
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Cache<Key, Value> implements ICache<Key, Value> {
    private List<Key> keys = new ArrayList<Key>();
    private List<Value> values = new ArrayList<Value>();
    private Map<Key, Value> map = new HashMap<Key, Value>();

    public void add(Key key, Value value) {
        synchronized (this) {
            remove(key);
            keys.add(key);
            values.add(value);
            map.put(key, value);
        }
    }

    public void update(Key key, Value value) {
        synchronized (this) {
            if (containsKey(key)) {
                Value _value = map.get(key);
                if (_value == null)
                    values.add(value);
                else {
                    int v_pos = values.indexOf(_value);
                    if (v_pos == -1)
                        values.add(value);
                    else {
                        values.remove(_value);
                        values.add(v_pos, value);
                    }
                }
                map.remove(key);
                map.put(key, value);
            }
        }
    }

    public void clear() {
        synchronized (this) {
            keys.clear();
            values.clear();
            map.clear();
        }
    }

    public void remove(Key key) {
        synchronized (this) {
            if (containsKey(key)) {
                keys.remove(key);
                Value _value = map.get(key);
                values.remove(_value);
                map.remove(key);
            }
        }
    }

    public Value get(Key key) {
        synchronized (this) {
            Value ret = map.get(key);
            return ret;
        }
    }

    public Key keyAt(int at) {
        Key ret = null;
        synchronized (this) {
            try {
                ret = keys.get(at);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    public Value valueAt(int at) {
        Value ret = null;
        synchronized (this) {
            try {
                ret = values.get(at);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    public int size() {
        synchronized (this) {
            int ret = map.size();
            return ret;
        }
    }

    public boolean containsKey(Key key) {
        synchronized (this) {
            boolean ret = keys.contains(key);
            return ret;
        }
    }

    public boolean containsValue(Value value) {
        synchronized (this) {
            boolean ret = values.contains(value);
            return ret;
        }
    }

    public List<Key> keys() {
        List<Key> ret = new ArrayList<Key>();
        synchronized (this) {
            for (Key key : keys)
                ret.add(key);
        }
        return ret;
    }

    public List<Value> values() {
        List<Value> ret = new ArrayList<Value>();
        synchronized (this) {
            for (Value value : values)
                ret.add(value);
        }
        return ret;
    }
}
